package cn.aiyuan.controller;

/**
 * @author wy
 * @date 2020/11/16
 */

import cn.aiyuan.constant.GlobalConstant;
import cn.aiyuan.dto.LoginDTO;
import cn.aiyuan.pojo.base.JsonData;
import cn.aiyuan.security.utils.SecurityHelper;
import cn.aiyuan.security.utils.SecurityUserData;
import cn.aiyuan.service.AccountService;
import cn.aiyuan.utils.JwtTokenUtil;
import com.baomidou.mybatisplus.extension.api.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

/**
 * @author aiyuan
 * @since 2020-09-18 13:50:27
 */
@Slf4j
@Validated
@Api(value = "认证", tags = "认证")
@RestController
@RequestMapping("/authorization")
public class AuthorizationController {

    @Resource
    private AccountService accountService;

    @Value("${jwt.expiration}")
    private long expirationMilliSeconds;

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private UserDetailsService userDetailsService;



    @ApiOperation("用户认证")
    @PostMapping
    public JsonData createAuthenticationToken(@RequestBody @Valid LoginDTO loginDTO) {
        try {
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginDTO.getUsername(), loginDTO.getPassword()));
        } catch (DisabledException e) {
            return JsonData.fail("系统验证失败");
        } catch (BadCredentialsException e) {
            return JsonData.fail("用户名或密码错误");
        }
        UserDetails userDetails = userDetailsService.loadUserByUsername(loginDTO.getUsername());
        //封装redis集合
        String key = GlobalConstant.USER_TOKEN.getValue() + userDetails.getUsername();
        //获取token
        String token = jwtTokenUtil.generateToken(userDetails);
        //放入redis
        stringRedisTemplate.opsForValue().set(key,token, expirationMilliSeconds, TimeUnit.SECONDS);

        return JsonData.ok(token,"登录成功");
    }


    @ApiOperation("用户登出")
    @PostMapping(value = "/logout")
    public JsonData logout() {
        SecurityUserData currentUser = SecurityHelper.getCurrentUser();
        stringRedisTemplate.delete(GlobalConstant.USER_TOKEN.getValue() + currentUser.getAccountNum());
        return JsonData.ok("退出成功");
    }
}
